package com.demo.webapp.kcfinder.freemarker;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import freemarker.template.ObjectWrapper;
import freemarker.template.SimpleHash;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;

/**
 * Http范围的Hash模型
 * warp封装模式,对Http内容进行封装.
 * 方便应用取得数据
 * 取得顺序：
 * 父hash -> 固定内容模型 -> request -> session -> context
 * @author ryuu.kk
 *
 */
public class HttpScopesHashModel extends SimpleHash {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2469983276669797803L;
	
	protected final ObjectWrapper wrapper;
	protected final ServletContext context;
	protected final HttpServletRequest request;
	protected Map<String, Object> resultMap;
	
    private final Map<String, TemplateModel> unlistedModels = new HashMap<String, TemplateModel>();
    
	public HttpScopesHashModel(ObjectWrapper wrapper, ServletContext context, HttpServletRequest request, Map<String, Object> resultMap) {
		super(resultMap);
        this.wrapper = wrapper;
        this.context = context;
        this.request = request;
		this.resultMap = resultMap; 
	}

    public void putUnlistedModel(String key, TemplateModel model) {
        unlistedModels.put(key, model);
    }
    
    public TemplateModel get(String key) throws TemplateModelException {
    	
    	// Lookup in result map
        TemplateModel model = super.get(key);
        if(model != null) {
            return model;
        }
		
        // Look in unlisted models
        model = (TemplateModel) unlistedModels.get(key);
        if(model != null) {
            return model;
        }
        
        // Lookup in request scope
        Object obj = request.getAttribute(key);
        if(obj != null) {
            return wrapper.wrap(obj);
        }

        // Lookup in session scope
        HttpSession session = request.getSession(false);
        if(session != null) {
            obj = session.getAttribute(key);
            if(obj != null) {
                return wrapper.wrap(obj);
            }
        }

        // Lookup in application scope
        obj = context.getAttribute(key);
        if(obj != null) {
            return wrapper.wrap(obj);
        }

        // return wrapper's null object (probably null).        
        return wrapper.wrap(null);
    }
}
